package com.wenlin.myproduction.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Shader;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;

import com.wenlin.myproduction.R;
import com.wenlin.myproduction.bean.InOutRecordBean;
import com.wenlin.myproduction.util.Checker;

import java.util.List;

/**
 * @desc: 借还走势图
 * @author: 文琳
 * @time: 2025/11/12 周三 17:13
 */
public class InOutChartView extends View {
    private static final int MARGIN_START = 30;
    private static final int MARGIN_END = 30;
    private static final int MARGIN_BOTTOM = 80;
    private static final int MARGIN_TOP = 80;
    private static final int DASH_WIDTH = 20;
    private static final int TEXT_MARGIN_END = 5;

    private Paint paint;
    private TextPaint textPaint;
    private int viewWidth;
    private int viewHeight;
    private List<InOutRecordBean> list;
    private float max;
    private Rect rect;
    private Path path;
    @ColorInt
    private int colorText = Color.parseColor("#ffffffff");
    @ColorInt
    private int colorDash = Color.parseColor("#ffffffff");
    private int valueWidth;
    private int valueHeight;
    private float totalStart;
    private float firstEndY;
    private float firstTotalTemp;
    private float lastEndY;
    private float lastTotalTemp;
    private float maxEndY;
    private float maxEndX;
    private float textLength;
    private String textDateStart;
    private String textDateEnd;
    private String textDateMax;

    public InOutChartView(Context context) {
        this(context, null);
    }

    public InOutChartView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        paint.setDither(true);

        textPaint = new TextPaint();
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setAntiAlias(true);
        textPaint.setDither(true);
        textPaint.setColor(colorText);
        textPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.wpx40));

        rect = new Rect();
        path = new Path();
    }

    /**
     * 设置数据和初始值
     */
    public void setData(List<InOutRecordBean> newList, float totalStart) {
        if (newList.isEmpty()) return;
        this.list = newList;
        //得到最大值
        this.totalStart = totalStart;
        float total = totalStart;
        //判断是否全都是还款，如果是就全都取反。让其看起来跟全是借款差不多的样式。
        boolean allIn = true;
        for (int i = 0; i < list.size(); i++) {
            try {
                if (Float.parseFloat(list.get(i).getMoney()) < 0) {
                    allIn = false;
                    break;
                }
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        if (allIn) {
            this.totalStart = 0f;
            for (int i = 0; i < list.size(); i++) {
                list.get(i).setMoney("-" + list.get(i).getMoney());
            }
        }
        max = 0f;
        for (int i = 0; i < list.size(); i++) {
            float money = Float.parseFloat(list.get(i).getMoney());
            total -= money;
            max = Math.max(max, total);
        }
        textDateStart = list.get(0).getDate();
        textDateEnd = list.get(list.size() - 1).getDate();
        invalidate();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        viewWidth = w;
        viewHeight = h;
        paint.setShader(new LinearGradient(0f, 0f, viewWidth, 0f, Color.parseColor("#ff1dc9e3"), Color.parseColor("#ff1de6ba"), Shader.TileMode.CLAMP));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (viewWidth <= 0 || viewHeight <= 0) return;
        valueWidth = viewWidth - MARGIN_START - MARGIN_END;
        valueHeight = viewHeight - MARGIN_BOTTOM - MARGIN_TOP;
        //画x坐标轴
        canvas.drawLine(MARGIN_START, viewHeight - MARGIN_BOTTOM, viewWidth - MARGIN_END, viewHeight - MARGIN_BOTTOM, textPaint);
        //画y坐标轴
        canvas.drawLine(MARGIN_START, MARGIN_TOP, MARGIN_START, viewHeight - MARGIN_BOTTOM, textPaint);
        //画净剩
        if (Checker.hasList(list)) {
            float totalTemp = totalStart;
            path.reset();
            float lastX = MARGIN_START;
            float lastY = viewHeight - MARGIN_BOTTOM;
            path.moveTo(lastX, lastY);
            int chartWidth = valueWidth / list.size();
            for (int i = 0; i < list.size(); i++) {
                if (i == 0) {
                    lastY = viewHeight - MARGIN_BOTTOM - totalTemp / max * valueHeight;
                    path.lineTo(lastX, lastY);
                    firstEndY = lastY;
                    firstTotalTemp = totalTemp;
                }
                float money = Float.parseFloat(list.get(i).getMoney());
                totalTemp -= money;
                float endX = MARGIN_START + (i + 1) * chartWidth;
                float endY = viewHeight - MARGIN_BOTTOM - totalTemp / max * valueHeight;
                float midX = (endX + lastX) / 2f;
                path.cubicTo(midX, lastY, midX, endY, endX, endY);
                float textWidth = textPaint.measureText(String.valueOf(i + 1));
                float start = endX - textWidth / 2f;
                if (i == list.size() - 1) {
                    float s;
                    if (endX + textWidth / 2f > viewWidth) //如果数字多，依然要显示完全
                        s = viewWidth - textWidth;
                    else s = endX - textWidth / 2f;
                    canvas.drawText(String.valueOf(i + 1), s, MARGIN_TOP / 2f, textPaint);
                } else if (start > textLength && start < (viewWidth - MARGIN_END - 2 * textPaint.measureText(String.valueOf(list.size())))
                ) {//为最后一个值留出空间
                    canvas.drawText(String.valueOf(i + 1), endX - textWidth / 2f, MARGIN_TOP / 2f, textPaint);
                    textLength = endX + textWidth / 2f;
                }
                lastX = endX;
                lastY = endY;
                if (i == list.size() - 1) {
                    lastEndY = endY;
                    lastTotalTemp = totalTemp;
                }
                if (totalTemp == max) {
                    maxEndY = endY;
                    maxEndX = endX;
                    textDateMax = list.get(i).getDate();
                }
            }
        }
        path.lineTo(viewWidth - MARGIN_END, viewHeight - MARGIN_BOTTOM);
        path.lineTo(MARGIN_START, viewHeight - MARGIN_BOTTOM);
        path.close();
        canvas.drawPath(path, paint);
        //画0
        drawText(canvas, 0f, MARGIN_START + TEXT_MARGIN_END, viewHeight - MARGIN_BOTTOM);
        //画最后一个值的虚线和字
        drawDash(canvas, lastEndY);
        drawText(canvas, lastTotalTemp, viewWidth - MARGIN_END - textPaint.measureText(String.valueOf(lastTotalTemp)) - TEXT_MARGIN_END, lastEndY);
        if (maxEndY != lastEndY && max != 0f && maxEndY > 0) {//如果最后的值就是最大值，就不需要再画了
            //画最大值的虚线和字
            drawDash(canvas, maxEndY);
            drawText(canvas, max, maxEndX - textPaint.measureText(String.valueOf(max)) / 2f, maxEndY);
        }
        if (firstEndY != lastEndY && totalStart != 0f) {//如果第一个值就是最后的值，就不需要再画了
            //画第一个值的虚线和字
            drawDash(canvas, firstEndY);
            drawText(canvas, totalStart, MARGIN_START + TEXT_MARGIN_END, firstEndY);
        }
        //画初始和结束的时间
        drawText(canvas, textDateStart, MARGIN_START * 2 + TEXT_MARGIN_END, viewHeight - MARGIN_BOTTOM * 3 / 5f);
        if (!textDateEnd.equals(textDateStart))
            drawText(canvas, textDateEnd, viewWidth - MARGIN_END * 2 - textPaint.measureText(String.valueOf(lastTotalTemp)) - TEXT_MARGIN_END, viewHeight - MARGIN_BOTTOM * 3 / 5f);
        if (Checker.hasWord(textDateMax) && !textDateMax.equals(textDateStart) && !textDateMax.equals(textDateEnd))
            drawText(canvas, textDateMax, maxEndX - textPaint.measureText(textDateMax) / 2f, viewHeight - MARGIN_BOTTOM * 3 / 5f);
    }

    /**
     * 函数内部嵌套函数——画虚线
     */
    private void drawDash(Canvas canvas, float y) {
        textPaint.setColor(colorDash);
        int startX = MARGIN_START;
        while (startX < (viewWidth - MARGIN_END)) {
            canvas.drawLine(startX, y, startX + DASH_WIDTH / 2f, y, textPaint);
            startX += DASH_WIDTH;
            canvas.drawLine(startX, y, startX + DASH_WIDTH / 2f, y, textPaint);
            startX += DASH_WIDTH / 2;
        }
        textPaint.setColor(colorText);
    }

    /**
     * 函数内部嵌套函数——画文字
     */
    private void drawText(Canvas canvas, String str, float x, float y) {
        textPaint.getTextBounds(str, 0, str.length(), rect);
        canvas.drawText(str, x, y + rect.height() / 2f, textPaint);
    }

    /**
     * 函数内部嵌套函数——画文字
     */
    private void drawText(Canvas canvas, float value, float x, float y) {
        drawText(canvas, String.valueOf(value), x, y);
    }
}
